home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 51 / Amiga Format CD51 (2000-03-10)(Future Publishing)(GB)[!][issue 2000-04].iso / -in_the_mag- / workbench / term_4.8 / extras / source / term-source.lha / Console.c < prev    next >
C/C++ Source or Header  |  1997-07-12  |  26KB  |  1,402 lines

  1. /*
  2. **    Console.c
  3. **
  4. **    High-level terminal console routines
  5. **
  6. **    Copyright © 1990-1997 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* Temporary console working buffer. */
  17.  
  18. STATIC UBYTE ConTempBuffer[512];
  19.  
  20. typedef VOID (* CALLBACK)(STRPTR,LONG);
  21.  
  22. /* How this stuff works:
  23.  *
  24.  *    This file holds the text output routines. The main entry point is
  25.  *    ConTransfer (actually a function pointer). This routine feeds the
  26.  *    input buffer into XProtocolHostMon(), a callback routine of the
  27.  *    currently active XPR library. Control then passes to ConProcess().
  28.  *    The incoming data is filtered through the flow scanner (FlowFilter),
  29.  *    passed through the capture routines (CaptureData), the script recorder
  30.  *    (RememberOutputText) and the trap scanner (TrapFilter). The data then
  31.  *    goes through the text processing routine ConProcessData (another
  32.  *    function pointer) which processes the embedded control sequences and
  33.  *    eventually feeds the raw text into ConDump (yet another function
  34.  *    pointer). This routine does the final text output.
  35.  */
  36.  
  37.     /* GfxText(struct RastPort *RPort,STRPTR Buffer,LONG Length):
  38.      *
  39.      *    Text output, if necessary switching from gfx font
  40.      *    to current default font.
  41.      */
  42.  
  43. VOID
  44. GfxText(struct RastPort *RPort,STRPTR Buffer,LONG Length)
  45. {
  46.         /* Character set modes. */
  47.  
  48.     enum { MODE_STANDARD,MODE_GFX };
  49.  
  50.     struct TextFont *Font;
  51.     WORD TextMode;
  52.     LONG SameMode;
  53.  
  54.         /* Determine current text rendering mode. */
  55.  
  56.     TextMode = GfxTable[Buffer[0]];
  57.  
  58.     if(TextMode == MODE_GFX)
  59.         Font = GFX;
  60.     else
  61.         Font = TextFont;
  62.  
  63.     SetFont(RPort,Font);
  64.  
  65.         /* Reset number of characters in common mode. */
  66.  
  67.     SameMode = 0;
  68.  
  69.         /* Scan until all input is processed. */
  70.  
  71.     do
  72.     {
  73.             /* Scan for characters in the current mode. */
  74.  
  75.         while(GfxTable[Buffer[SameMode]] == TextMode && SameMode < Length)
  76.             SameMode++;
  77.  
  78.             /* Output the text found. */
  79.  
  80.         Text(RPort,Buffer,SameMode);
  81.  
  82.             /* Decrement number of remaining bytes. */
  83.  
  84.         Length -= SameMode;
  85.  
  86.             /* Anything left? */
  87.  
  88.         if(Length > 0)
  89.         {
  90.                 /* Skip to next character. */
  91.  
  92.             Buffer += SameMode;
  93.             SameMode = 0;
  94.  
  95.                 /* Change text output mode. */
  96.  
  97.             if(TextMode == MODE_GFX)
  98.             {
  99.                 TextMode = MODE_STANDARD;
  100.                 Font = TextFont;
  101.             }
  102.             else
  103.             {
  104.                 TextMode = MODE_GFX;
  105.                 Font = GFX;
  106.             }
  107.  
  108.             SetFont(RPort,Font);
  109.         }
  110.     }
  111.     while(Length > 0);
  112.  
  113.         /* Reset font type. */
  114.  
  115.     if(TextMode == MODE_GFX)
  116.         SetFont(RPort,TextFont);
  117. }
  118.  
  119. /****************************************************************************/
  120.  
  121.     /* ConTranslateSetup():
  122.      *
  123.      *    Set up for buffer translation.
  124.      */
  125.  
  126. STATIC VOID
  127. ConTranslateSetup(struct TranslationHandle *Handle,STRPTR SourceBuffer,LONG SourceLen,STRPTR DestinationBuffer,LONG DestinationLen,struct TranslationEntry **Table)
  128. {
  129.     Handle->LocalBuffer            = NULL;
  130.     Handle->LocalLen            = 0;
  131.  
  132.     Handle->SourceBuffer        = SourceBuffer;
  133.     Handle->SourceLen            = SourceLen;
  134.  
  135.     Handle->DestinationBuffer    = DestinationBuffer;
  136.     Handle->DestinationLen        = DestinationLen;
  137.  
  138.     Handle->Table                = Table;
  139. }
  140.  
  141.     /* ConTranslateBuffer(struct TranslationHandle *Handle):
  142.      *
  143.      *    Translate buffer contents according to
  144.      *    translation table contents.
  145.      */
  146.  
  147. STATIC LONG
  148. ConTranslateBuffer(struct TranslationHandle *Handle)
  149. {
  150.     struct TranslationEntry *Entry;
  151.     LONG BytesWritten;
  152.     STRPTR Data;
  153.  
  154.     Data = Handle->DestinationBuffer;
  155.     BytesWritten = 0;
  156.  
  157.         /* Are we to return any translated data? */
  158.  
  159.     while(Handle->LocalLen && BytesWritten < Handle->DestinationLen)
  160.     {
  161.             /* Decrement number of bytes in buffer. */
  162.  
  163.         Handle->LocalLen--;
  164.  
  165.             /* Return next character. */
  166.  
  167.         *Data++ = *Handle->LocalBuffer++;
  168.  
  169.             /* Add another byte. */
  170.  
  171.         BytesWritten++;
  172.     }
  173.  
  174.         /* Loop until done. */
  175.  
  176.     while(Handle->SourceLen && BytesWritten < Handle->DestinationLen)
  177.     {
  178.             /* Another byte eaten. */
  179.  
  180.         Handle->SourceLen--;
  181.  
  182.             /* Get table entry. */
  183.  
  184.         if(Entry = Handle->Table[*Handle->SourceBuffer++])
  185.         {
  186.                 /* Copy to local data area. */
  187.  
  188.             Handle->LocalBuffer    = Entry->String;
  189.             Handle->LocalLen    = Entry->Len;
  190.  
  191.                 /* Translate the data. */
  192.  
  193.             while(Handle->LocalLen && BytesWritten < Handle->DestinationLen)
  194.             {
  195.                     /* Decrement number of bytes in buffer. */
  196.  
  197.                 Handle->LocalLen--;
  198.  
  199.                     /* Return next character. */
  200.  
  201.                 *Data++ = *Handle->LocalBuffer++;
  202.  
  203.                     /* Add another byte. */
  204.  
  205.                 BytesWritten++;
  206.             }
  207.         }
  208.     }
  209.  
  210.     return(BytesWritten);
  211. }
  212.  
  213.     /* ConOutputTranslate(STRPTR Buffer,LONG Size):
  214.      *
  215.      *    Frontend for ConOutput(), including character translation.
  216.      */
  217.  
  218. STATIC VOID
  219. ConOutputTranslate(STRPTR Buffer,LONG Size)
  220. {
  221.     struct TranslationHandle Handle;
  222.     UBYTE LocalBuffer[256];
  223.  
  224.         /* Set up for translation. */
  225.  
  226.     ConTranslateSetup(&Handle,Buffer,Size,LocalBuffer,sizeof(LocalBuffer),ReceiveTable);
  227.  
  228.         /* Process and output the data. */
  229.  
  230.     while(Size = ConTranslateBuffer(&Handle))
  231.         (* ConOutput)(LocalBuffer,Size);
  232. }
  233.  
  234. /****************************************************************************/
  235.  
  236.     /* ConOutputPrinter(STRPTR Buffer,LONG Size):
  237.      *
  238.      *    Raw text output routine, printer capture flavour.
  239.      */
  240.  
  241. STATIC VOID
  242. ConOutputPrinter(STRPTR Buffer,LONG Size)
  243. {
  244.     if(Write(PrinterCapture,Buffer,Size) != Size)
  245.     {
  246.         BlockWindows();
  247.  
  248.         if(!ShowRequest(NULL,LocaleString(MSG_CONSOLE_ERROR_WRITING_TO_PRINTER_TXT),LocaleString(MSG_CONSOLE_IGNORE_CLOSE_PRINTER_TXT)))
  249.             ClosePrinterCapture(TRUE);
  250.  
  251.         ReleaseWindows();
  252.     }
  253. }
  254.  
  255.     /* ConOutputGFX(STRPTR Buffer,LONG Size):
  256.      *
  257.      *    Raw text output routine, GFX text flavour.
  258.      */
  259.  
  260. STATIC VOID
  261. ConOutputGFX(STRPTR Buffer,LONG Size)
  262. {
  263.     LONG Offset;
  264.  
  265.         /* Do we still have a character in the
  266.          * magnificient buffer?
  267.          */
  268.  
  269.     while(Size)
  270.     {
  271.             /* Cursor is positioned at
  272.              * the right hand side of the
  273.              * display. If auto-wrap is
  274.              * enabled, perform some
  275.              * kind of CR/LF, else leave
  276.              * the cursor where it is and
  277.              * quit the show.
  278.              */
  279.  
  280.         if(CursorX > LastPrintableColumn)
  281.         {
  282.                 /* Wrap cursor. */
  283.  
  284.             if(Config->EmulationConfig->LineWrap)
  285.             {
  286.                     /* Move to beginning of next line. */
  287.  
  288.                 CursorX = 0;
  289.  
  290.                 DownLine();
  291.  
  292.                     /* Reposition cursor, don't redraw it. */
  293.  
  294.                 RepositionCursor();
  295.             }
  296.             else
  297.             {
  298.                     /* Stop the cursor. */
  299.  
  300.                 CursorX = LastPrintableColumn;
  301.  
  302.                     /* Make it reappear. */
  303.  
  304.                 RepositionCursor();
  305.  
  306.                 return;
  307.             }
  308.         }
  309.  
  310.         if((Offset = LastPrintableColumn + 1 - CursorX) > Size)
  311.             Offset = Size;
  312.  
  313.         if(Config->EmulationConfig->InsertMode)
  314.         {
  315.             RasterShiftChar(Offset);
  316.  
  317.             ScrollLineShiftChar(Offset);
  318.  
  319.             ShiftChar(Offset);
  320.         }
  321.  
  322.         RasterPutString(Buffer,Offset);
  323.  
  324.         ScrollLinePutString(Offset);
  325.  
  326.         if(FontScalingRequired)
  327.             PrintScaled(Buffer,Offset,CurrentFontScale);
  328.         else
  329.             GfxText(RPort,Buffer,Offset);
  330.  
  331.         Buffer    += Offset;
  332.  
  333.         Size    -= Offset;
  334.  
  335.         CursorX    += Offset;
  336.     }
  337.  
  338.     RepositionCursor();
  339. }
  340.  
  341.     /* ConOutputNormal(STRPTR Buffer,LONG Size):
  342.      *
  343.      *    Raw text output routine, normal text flavour.
  344.      */
  345.  
  346. STATIC VOID
  347. ConOutputNormal(STRPTR Buffer,LONG Size)
  348. {
  349.     LONG Offset;
  350.  
  351.     while(Size)
  352.     {
  353.         if(CursorX > LastPrintableColumn)
  354.         {
  355.             if(Config->EmulationConfig->LineWrap)
  356.             {
  357.                 CursorX = 0;
  358.  
  359.                 DownLine();
  360.  
  361.                 RepositionCursor();
  362.             }
  363.             else
  364.             {
  365.                 CursorX = LastPrintableColumn;
  366.  
  367.                 RepositionCursor();
  368.  
  369.                 return;
  370.             }
  371.         }
  372.  
  373.         if((Offset = LastPrintableColumn + 1 - CursorX) > Size)
  374.             Offset = Size;
  375.  
  376.         if(Config->EmulationConfig->InsertMode)
  377.         {
  378.             RasterShiftChar(Offset);
  379.  
  380.             ScrollLineShiftChar(Offset);
  381.  
  382.             ShiftChar(Offset);
  383.         }
  384.  
  385.         RasterPutString(Buffer,Offset);
  386.  
  387.         ScrollLinePutString(Offset);
  388.  
  389.         if(FontScalingRequired)
  390.             PrintScaled(Buffer,Offset,CurrentFontScale);
  391.         else
  392.             Text(RPort,Buffer,Offset);
  393.  
  394.         Buffer    += Offset;
  395.         Size    -= Offset;
  396.         CursorX    += Offset;
  397.     }
  398.  
  399.     RepositionCursor();
  400. }
  401.  
  402. /****************************************************************************/
  403.  
  404.     /* ConProcessDataTransExternal(STRPTR String,LONG Size):
  405.      *
  406.      *    Process data, external emulation including translation flavour.
  407.      */
  408.  
  409. STATIC VOID
  410. ConProcessDataTransExternal(STRPTR String,LONG Size)
  411. {
  412.     struct TranslationHandle Handle;
  413.  
  414.         /* Set up for translation. */
  415.  
  416.     ConTranslateSetup(&Handle,String,Size,ConTempBuffer,sizeof(ConTempBuffer) / 2,ReceiveTable);
  417.  
  418.     if(StripBuffer)
  419.     {
  420.         LONG Len;
  421.  
  422.             /* Process and output the data. */
  423.  
  424.         while(Size = ConTranslateBuffer(&Handle))
  425.         {
  426.             XEmulatorWrite(XEM_IO,ConTempBuffer,Size);
  427.  
  428.             XEM_HostData.Source            = ConTempBuffer;
  429.             XEM_HostData.Destination    = StripBuffer;
  430.  
  431.             if(Len = XEmulatorHostMon(XEM_IO,&XEM_HostData,Size))
  432.             {
  433.                 if(CaptureData)
  434.                     (*CaptureData)(StripBuffer,Len);
  435.             }
  436.         }
  437.     }
  438.     else
  439.     {
  440.             /* Process and output the data. */
  441.  
  442.         while(Size = ConTranslateBuffer(&Handle))
  443.             XEmulatorWrite(XEM_IO,ConTempBuffer,Size);
  444.     }
  445. }
  446.  
  447.     /* ConProcessDataExternal(STRPTR String,LONG Size):
  448.      *
  449.      *    Process data, external emulation flavour.
  450.      */
  451.  
  452. STATIC VOID
  453. ConProcessDataExternal(STRPTR String,LONG Size)
  454. {
  455.     XEmulatorWrite(XEM_IO,String,Size);
  456.  
  457.         /* Build another string to contain
  458.          * the pure ASCII contents, i.e.
  459.          * not including any ESC control
  460.          * sequences.
  461.          */
  462.  
  463.     if(StripBuffer)
  464.     {
  465.         LONG Len;
  466.  
  467.         XEM_HostData.Source            = String;
  468.         XEM_HostData.Destination    = StripBuffer;
  469.  
  470.         if(Len = XEmulatorHostMon(XEM_IO,&XEM_HostData,Size))
  471.         {
  472.             if(CaptureData)
  473.                 (*CaptureData)(StripBuffer,Len);
  474.         }
  475.     }
  476. }
  477.  
  478.     /* ConProcessDataGeneric(STRPTR String,LONG Size,Mask):
  479.      *
  480.      *    Process data, generic flavour.
  481.      */
  482.  
  483. STATIC VOID
  484. ConProcessDataGeneric(STRPTR String,LONG Size,UBYTE Mask)
  485. {
  486.     LONG    Len = 0;
  487.     UBYTE    c;
  488.  
  489.         /* If still parsing a sequence,
  490.          * continue with it.
  491.          */
  492.  
  493.     if(InSequence)
  494.     {
  495.         while(Size--)
  496.         {
  497.             c = *String++ & Mask;
  498.  
  499.             if(!(*AbortTable[c])(c))
  500.             {
  501.                 InSequence = FALSE;
  502.  
  503.                 break;
  504.             }
  505.         }
  506.     }
  507.  
  508.         /* Check which font we are in, if other than Topaz
  509.          * the only invalid char is a Null (0) which will
  510.          * display as a space if let to continue.
  511.          */
  512.  
  513.     if(Config->TerminalConfig->FontMode == FONT_STANDARD)
  514.     {
  515.         while(Size-- > 0)
  516.         {
  517.             if(IsPrintable[c = *String++ & Mask])
  518.             {
  519.                     /* This character is associated with a
  520.                      * special function (bell, xon, xoff, etc.).
  521.                      */
  522.  
  523.                 if(SpecialTable[c])
  524.                 {
  525.                     if(Len)
  526.                     {
  527.                         (*ConDump)(ConTempBuffer,Len);
  528.  
  529.                         Len = 0;
  530.                     }
  531.  
  532.                         /* Does this character start
  533.                          * a control sequence?
  534.                          */
  535.  
  536.                     if(InSequence = (*SpecialTable[c])(c))
  537.                     {
  538.                         while(Size-- > 0)
  539.                         {
  540.                             c = *String++ & Mask;
  541.  
  542.                             if(!(*AbortTable[c])(c))
  543.                             {
  544.                                 InSequence = FALSE;
  545.  
  546.                                 break;
  547.                             }
  548.                         }
  549.                     }
  550.                 }
  551.                 else
  552.                 {
  553.                         /* Put the character into the buffer
  554.                          * and flush it if necessary.
  555.                          */
  556.  
  557.                     ConTempBuffer[Len] = c;
  558.  
  559.                     if(Len++ == sizeof(ConTempBuffer))
  560.                     {
  561.                         (*ConDump)(ConTempBuffer,Len);
  562.  
  563.                         Len = 0;
  564.                     }
  565.                 }
  566.             }
  567.         }
  568.     }
  569.     else
  570.     {
  571.         while(Size-- > 0)
  572.         {
  573.             if(c = (*String++ & Mask))
  574.             {
  575.                     /* This character is associated with a
  576.                      * special function (bell, xon, xoff, etc.).
  577.                      */
  578.  
  579.                 if(SpecialTable[c])
  580.                 {
  581.                     if(Len)
  582.                     {
  583.                         (*ConDump)(ConTempBuffer,Len);
  584.  
  585.                         Len = 0;
  586.                     }
  587.  
  588.                     if(InSequence = (*SpecialTable[c])(c))
  589.                     {
  590.                         while(Size-- > 0)
  591.                         {
  592.                             c = *String++ & Mask;
  593.  
  594.                             if(!(*AbortTable[c])(c))
  595.                             {
  596.                                 InSequence = FALSE;
  597.  
  598.                                 break;
  599.                             }
  600.                         }
  601.                     }
  602.                 }
  603.                 else
  604.                 {
  605.                         /* Put the character into the buffer
  606.                          * and flush it if necessary.
  607.                          */
  608.  
  609.                     ConTempBuffer[Len] = c;
  610.  
  611.                     if(Len++ == sizeof(ConTempBuffer))
  612.                     {
  613.                         (*ConDump)(ConTempBuffer,Len);
  614.  
  615.                         Len = 0;
  616.                     }
  617.                 }
  618.             }
  619.         }
  620.     }
  621.  
  622.     if(Len)
  623.         (*ConDump)(ConTempBuffer,Len);
  624. }
  625.  
  626.     /* ConProcessData7(STRPTR String,LONG Size):
  627.      *
  628.      *    Process data, 7 bit flavour.
  629.      */
  630.  
  631. STATIC VOID
  632. ConProcessData7(STRPTR String,LONG Size)
  633. {
  634.     ConProcessDataGeneric(String,Size,0x7F);
  635. }
  636.  
  637.     /* ConProcessData8(STRPTR String,LONG Size):
  638.      *
  639.      *    Process data, 8 bit flavour.
  640.      */
  641.  
  642. STATIC VOID
  643. ConProcessData8(STRPTR String,LONG Size)
  644. {
  645.     LONG    Len = 0;
  646.     UBYTE    c;
  647.  
  648.     if(InSequence)
  649.     {
  650.         while(Size--)
  651.         {
  652.             c = *String++;
  653.  
  654.             if(!(*AbortTable[c])(c))
  655.             {
  656.                 InSequence = FALSE;
  657.  
  658.                 break;
  659.             }
  660.         }
  661.     }
  662.  
  663.     if(Config->TerminalConfig->FontMode == FONT_STANDARD)
  664.     {
  665.         while(Size-- > 0)
  666.         {
  667.             if(IsPrintable[c = *String++])
  668.             {
  669.                 if(SpecialTable[c])
  670.                 {
  671.                     if(Len)
  672.                     {
  673.                         (*ConDump)(ConTempBuffer,Len);
  674.  
  675.                         Len = 0;
  676.                     }
  677.  
  678.                     if(InSequence = (*SpecialTable[c])(c))
  679.                     {
  680.                         while(Size-- > 0)
  681.                         {
  682.                             c = *String++;
  683.  
  684.                             if(!(*AbortTable[c])(c))
  685.                             {
  686.                                 InSequence = FALSE;
  687.  
  688.                                 break;
  689.                             }
  690.                         }
  691.                     }
  692.                 }
  693.                 else
  694.                 {
  695.                     ConTempBuffer[Len] = c;
  696.  
  697.                     if(Len++ == sizeof(ConTempBuffer))
  698.                     {
  699.                         (*ConDump)(ConTempBuffer,Len);
  700.  
  701.                         Len = 0;
  702.                     }
  703.                 }
  704.             }
  705.         }
  706.     }
  707.     else
  708.     {
  709.         while(Size-- > 0)
  710.         {
  711.             if(c = *String++)
  712.             {
  713.                 if(SpecialTable[c])
  714.                 {
  715.                     if(Len)
  716.                     {
  717.                         (*ConDump)(ConTempBuffer,Len);
  718.  
  719.                         Len = 0;
  720.                     }
  721.  
  722.                     if(InSequence = (*SpecialTable[c])(c))
  723.                     {
  724.                         while(Size-- > 0)
  725.                         {
  726.                             c = *String++;
  727.  
  728.                             if(!(*AbortTable[c])(c))
  729.                             {
  730.                                 InSequence = FALSE;
  731.  
  732.                                 break;
  733.                             }
  734.                         }
  735.                     }
  736.                 }
  737.                 else
  738.                 {
  739.                     ConTempBuffer[Len] = c;
  740.  
  741.                     if(Len++ == sizeof(ConTempBuffer))
  742.                     {
  743.                         (*ConDump)(ConTempBuffer,Len);
  744.  
  745.                         Len = 0;
  746.                     }
  747.                 }
  748.             }
  749.         }
  750.     }
  751.  
  752.     if(Len)
  753.         (*ConDump)(ConTempBuffer,Len);
  754. }
  755.  
  756.     /* ConProcessDataHexGeneric(STRPTR String,LONG Size,UBYTE Mask):
  757.      *
  758.      *    Process data, hex mode flavour, generic version.
  759.      */
  760.  
  761. STATIC VOID
  762. ConProcessDataHexGeneric(STRPTR String,LONG Size,UBYTE Mask)
  763. {
  764.     UBYTE    DummyBuffer[40],c;
  765.     LONG    Fit,Spaces,Current;
  766.  
  767.         /* How many characters will fit into the line? */
  768.  
  769.     Fit    = (LastColumn + 1) / 4;
  770.  
  771.         /* Which position are we currently in? */
  772.  
  773.     Current    = CursorX / 3;
  774.  
  775.         /* Weird cursor position? */
  776.  
  777.     if(Current >= Fit || (CursorX % 3))
  778.     {
  779.         ConProcessDataGeneric("\r\n",2,Mask);
  780.  
  781.         Current = 0;
  782.     }
  783.  
  784.         /* Check the font type. */
  785.  
  786.     if(Config->TerminalConfig->FontMode == FONT_STANDARD)
  787.     {
  788.         while(Size-- > 0)
  789.         {
  790.             c = (*String++) & Mask;
  791.  
  792.             Spaces = (Fit - Current) * 3 + Current - 3;
  793.  
  794.             if(c > ' ' && c < 127)
  795.                 LimitedSPrintf(sizeof(DummyBuffer),DummyBuffer,"%02lx \33[%ldC%lc\33[%ldD",c,Spaces,c,Spaces + 1);
  796.             else
  797.                 LimitedSPrintf(sizeof(DummyBuffer),DummyBuffer,"%02lx \33[%ldC.\33[%ldD",c,Spaces,Spaces + 1);
  798.  
  799.             ConProcessDataGeneric(DummyBuffer,strlen(DummyBuffer),Mask);
  800.  
  801.             if(Current++ == Fit - 1)
  802.             {
  803.                 Current = 0;
  804.  
  805.                 ConProcessDataGeneric("\r\n",2,Mask);
  806.             }
  807.         }
  808.     }
  809.     else
  810.     {
  811.         while(Size-- > 0)
  812.         {
  813.             c = (*String++) & Mask;
  814.  
  815.             Spaces = (Fit - Current) * 3 + Current - 3;
  816.  
  817.             if(c && c != ' ')
  818.                 LimitedSPrintf(sizeof(DummyBuffer),DummyBuffer,"%02lx \33[%ldC%lc\33[%ldD",c,Spaces,c,Spaces + 1);
  819.             else
  820.                 LimitedSPrintf(sizeof(DummyBuffer),DummyBuffer,"%02lx \33[%ldC.\33[%ldD",c,Spaces,Spaces + 1);
  821.  
  822.             ConProcessDataGeneric(DummyBuffer,strlen(DummyBuffer),Mask);
  823.  
  824.             if(Current++ == Fit - 1)
  825.             {
  826.                 Current = 0;
  827.  
  828.                 ConProcessDataGeneric("\r\n",2,Mask);
  829.             }
  830.         }
  831.     }
  832. }
  833.  
  834.     /* ConProcessDataHex7(STRPTR String,LONG Size):
  835.      *
  836.      *    Process data, hex mode flavour, seven bits.
  837.      */
  838.  
  839. STATIC VOID
  840. ConProcessDataHex7(STRPTR String,LONG Size)
  841. {
  842.     ConProcessDataHexGeneric(String,Size,0x7F);
  843. }
  844.  
  845.     /* ConProcessDataHex8(STRPTR String,LONG Size):
  846.      *
  847.      *    Process data, hex mode flavour, eight bits.
  848.      */
  849.  
  850. STATIC VOID
  851. ConProcessDataHex8(STRPTR String,LONG Size)
  852. {
  853.     ConProcessDataHexGeneric(String,Size,0xFF);
  854. }
  855.  
  856. /****************************************************************************/
  857.  
  858.     /* ConTransferHost(STRPTR Buffer,LONG Len):
  859.      *
  860.      *    Process data read from the serial line,
  861.      *    special XPR flavour.
  862.      */
  863.  
  864. STATIC VOID
  865. ConTransferHost(STRPTR Buffer,LONG Len)
  866. {
  867.     LONG MaxSize;
  868.  
  869.         /* How much room is left? */
  870.  
  871.     if(Buffer != ReadBuffer)
  872.         MaxSize = SerialBufferSize - ((LONG)Buffer - (LONG)ReadBuffer);
  873.     else
  874.         MaxSize = SerialBufferSize;
  875.  
  876.         /* Let the XPR library take its share. */
  877.  
  878.     Len = XProtocolHostMon(XprIO,Buffer,Len,MaxSize);
  879.  
  880.         /* Did a file transfer start? */
  881.  
  882.     if(TransferWindow)
  883.         TransferCleanup();
  884.  
  885.         /* If the file transfer was aborted, flush the receive buffer. */
  886.  
  887.     if(TransferAborted)
  888.     {
  889.         BlockWindows();
  890.  
  891.         CompletelyFlushSerialRead();
  892.  
  893.         ReleaseWindows();
  894.  
  895.         TransferAborted = FALSE;
  896.     }
  897.  
  898.         /* Reset these two. */
  899.  
  900.     TransferFailed = TransferError = FALSE;
  901.  
  902.     if(Len)
  903.         ConProcess(Buffer,Len);
  904. }
  905.  
  906.     /* ConRawOutput(STRPTR String):
  907.      *
  908.      *    Bypass the `normal' ConOutput() data processing.
  909.      */
  910.  
  911. STATIC VOID
  912. ConRawOutput(STRPTR String)
  913. {
  914.     CALLBACK ProcessData;
  915.  
  916.     if(Config->SerialConfig->StripBit8)
  917.         ProcessData = (CALLBACK)ConProcessData7;
  918.     else
  919.         ProcessData = (CALLBACK)ConProcessData8;
  920.  
  921.     if(Marking)
  922.         WindowMarkerStop();
  923.  
  924.     ClearCursor();
  925.  
  926.     (*ProcessData)(String,strlen(String));
  927.  
  928.     DrawCursor();
  929. }
  930.  
  931. STATIC VOID
  932. ConTransferHost_Translate_CR_LF(STRPTR String,LONG Size)
  933. {
  934.     LONG MaxSize;
  935.  
  936.     if(String != ReadBuffer)
  937.         MaxSize = SerialBufferSize - ((LONG)String - (LONG)ReadBuffer);
  938.     else
  939.         MaxSize = SerialBufferSize;
  940.  
  941.     Size = XProtocolHostMon(XprIO,String,Size,MaxSize);
  942.  
  943.     if(TransferWindow)
  944.         TransferCleanup();
  945.  
  946.     if(Size > 0)
  947.     {
  948.         if(Size = (*Translate_CR_LF)(String,Size))
  949.             ConProcess(String,Size);
  950.     }
  951. }
  952.  
  953. STATIC VOID
  954. ConProcess_Translate_CR_LF(STRPTR String,LONG Size)
  955. {
  956.     if(Size = (*Translate_CR_LF)(String,Size))
  957.         ConProcess(String,Size);
  958. }
  959.  
  960.     /* ConProcess(STRPTR String,LONG Size):
  961.      *
  962.      *    This is the central entry point to the terminal window
  963.      *    output routines. The incoming data is filtered through
  964.      *    the flow scanner (FlowFilter), passed through the capture
  965.      *    routines (CaptureData), the script recorder (RememberOutputText)
  966.      *    and the trap scanner (TrapFilter).
  967.      */
  968.  
  969. VOID
  970. ConProcess(STRPTR String,LONG Size)
  971. {
  972.     if(Size > 0)
  973.     {
  974.             /* Feed the flow filter. */
  975.  
  976.         if(UseFlow)
  977.             Size = FlowFilter(String,Size,Config->SerialConfig->StripBit8 ? 0x7F : 0xFF);
  978.  
  979.             /* In quiet mode no characters are echoed to the
  980.              * console window, they are just passed through
  981.              * the data flow filter. Usually, this mode is
  982.              * enabled by the dial panel.
  983.              */
  984.  
  985.         if(!ConsoleQuiet && Size > 0)
  986.         {
  987.                 /* Capture the data. */
  988.  
  989.             if(CaptureData && !XEmulatorBase)
  990.             {
  991.                 if(Config->CaptureConfig->ConvertChars && Config->TerminalConfig->FontMode != FONT_STANDARD)
  992.                 {
  993.                     UBYTE     LocalBuffer[BUFFER_LINE_MAX];
  994.                     UBYTE    *Src = String,*Dst,c;
  995.                     ULONG     Count,Len = Size;
  996.  
  997.                     while(Len > 0)
  998.                     {
  999.                         Count = MIN(BUFFER_LINE_MAX,Len);
  1000.                         Len -= Count;
  1001.                         Dst = LocalBuffer;
  1002.  
  1003.                         do
  1004.                         {
  1005.                             if(c = ISOConversion[*Src++])
  1006.                                 *Dst++ = c;
  1007.                             else
  1008.                                 *Dst++ = (UBYTE)'·';
  1009.                         }
  1010.                         while(--Count > 0);
  1011.  
  1012.                         if((Count = (ULONG)Dst - (ULONG)LocalBuffer) > 0)
  1013.                             (*CaptureData)(LocalBuffer,Count);
  1014.                     }
  1015.                 }
  1016.                 else
  1017.                     (*CaptureData)(String,Size);
  1018.             }
  1019.  
  1020.                 /* Remember the data. */
  1021.  
  1022.             if(RememberOutput)
  1023.                 RememberOutputText(String,Size);
  1024.  
  1025.                 /* Check the traps if necessary. */
  1026.  
  1027.             if(WatchTraps)
  1028.                 TrapFilter(String,Size);
  1029.  
  1030.             if(Marking)
  1031.                 WindowMarkerStop();
  1032.  
  1033.             ClearCursor();
  1034.  
  1035.             (*ConProcessData)(String,Size);
  1036.  
  1037.             DrawCursor();
  1038.         }
  1039.     }
  1040. }
  1041.  
  1042.     /* ConPrintf(STRPTR String,...):
  1043.      *
  1044.      *    Output a string to the console.
  1045.      */
  1046.  
  1047. VOID
  1048. ConPrintf(STRPTR String,...)
  1049. {
  1050.     UBYTE LocalBuffer[256];
  1051.     va_list    VarArgs;
  1052.  
  1053.     if(Marking)
  1054.         WindowMarkerStop();
  1055.  
  1056.     va_start(VarArgs,String);
  1057.     LimitedVSPrintf(sizeof(LocalBuffer),LocalBuffer,String,VarArgs);
  1058.     va_end(VarArgs);
  1059.  
  1060.     ConProcess(LocalBuffer,strlen(LocalBuffer));
  1061. }
  1062.  
  1063. /****************************************************************************/
  1064.  
  1065.     /* ConProcessUpdate():
  1066.      *
  1067.      *    Choose the right console data processing routine.
  1068.      */
  1069.  
  1070. VOID
  1071. ConProcessUpdate()
  1072. {
  1073.     Forbid();
  1074.  
  1075.     if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1076.     {
  1077.         if(ReceiveTable)
  1078.             ConProcessData = ConProcessDataTransExternal;
  1079.         else
  1080.             ConProcessData = ConProcessDataExternal;
  1081.     }
  1082.     else
  1083.     {
  1084.         if(Config->SerialConfig->StripBit8)
  1085.         {
  1086.             if(Config->TerminalConfig->EmulationMode == EMULATION_HEX)
  1087.                 ConProcessData = ConProcessDataHex7;
  1088.             else
  1089.                 ConProcessData = ConProcessData7;
  1090.         }
  1091.         else
  1092.         {
  1093.             if(Config->TerminalConfig->EmulationMode == EMULATION_HEX)
  1094.                 ConProcessData = ConProcessDataHex8;
  1095.             else
  1096.                 ConProcessData = ConProcessData8;
  1097.         }
  1098.     }
  1099.  
  1100.     Permit();
  1101. }
  1102.  
  1103.     /* ConOutputUpdate():
  1104.      *
  1105.      *    Choose the right raw text output routine for the job.
  1106.      */
  1107.  
  1108. VOID
  1109. ConOutputUpdate()
  1110. {
  1111.     Forbid();
  1112.  
  1113.     if(BufferFrozen || Config->CaptureConfig->BufferMode == BUFFERMODE_FLOW)
  1114.         SaveRaster = SaveRasterDummy;
  1115.     else
  1116.         SaveRaster = SaveRasterReal;
  1117.  
  1118.     if(BufferFrozen || Config->CaptureConfig->BufferMode != BUFFERMODE_FLOW)
  1119.     {
  1120.         if(FileCapture)
  1121.         {
  1122.             if(PrinterCapture)
  1123.             {
  1124.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1125.                     CaptureData = CaptureFilteredTo_File_Printer;
  1126.                 else
  1127.                     CaptureData = CaptureRawTo_File_Printer;
  1128.             }
  1129.             else
  1130.             {
  1131.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1132.                     CaptureData = CaptureFilteredTo_File;
  1133.                 else
  1134.                     CaptureData = CaptureRawTo_File;
  1135.             }
  1136.         }
  1137.         else
  1138.         {
  1139.             if(PrinterCapture)
  1140.             {
  1141.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1142.                     CaptureData = CaptureFilteredTo_Printer;
  1143.                 else
  1144.                     CaptureData = CaptureRawTo_Printer;
  1145.             }
  1146.             else
  1147.                 CaptureData = NULL;
  1148.         }
  1149.     }
  1150.     else
  1151.     {
  1152.         if(FileCapture)
  1153.         {
  1154.             if(PrinterCapture)
  1155.             {
  1156.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1157.                     CaptureData = CaptureFilteredTo_Buffer_File_Printer;
  1158.                 else
  1159.                     CaptureData = CaptureRawTo_Buffer_File_Printer;
  1160.             }
  1161.             else
  1162.             {
  1163.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1164.                     CaptureData = CaptureFilteredTo_Buffer_File;
  1165.                 else
  1166.                     CaptureData = CaptureRawTo_Buffer_File;
  1167.             }
  1168.         }
  1169.         else
  1170.         {
  1171.             if(PrinterCapture)
  1172.             {
  1173.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1174.                     CaptureData = CaptureFilteredTo_Buffer_Printer;
  1175.                 else
  1176.                     CaptureData = CaptureRawTo_Buffer_Printer;
  1177.             }
  1178.             else
  1179.             {
  1180.                 if(Config->CaptureConfig->CaptureFilterMode && !RawCapture)
  1181.                     CaptureData = CaptureFilteredTo_Buffer;
  1182.                 else
  1183.                     CaptureData = CaptureRawTo_Buffer;
  1184.             }
  1185.         }
  1186.     }
  1187.  
  1188.     if(ControllerActive)
  1189.         ConOutput = ConOutputPrinter;
  1190.     else
  1191.     {
  1192.         if(CurrentFont == GFX)
  1193.             ConOutput = ConOutputGFX;
  1194.         else
  1195.             ConOutput = ConOutputNormal;
  1196.     }
  1197.  
  1198.     if(ReceiveTable)
  1199.         ConDump = ConOutputTranslate;
  1200.     else
  1201.         ConDump = ConOutput;
  1202.  
  1203.     Permit();
  1204. }
  1205.  
  1206.     /* ConFontScaleUpdate():
  1207.      *
  1208.      *    Choose the right font scale for the job.
  1209.      */
  1210.  
  1211. VOID
  1212. ConFontScaleUpdate()
  1213. {
  1214.     CurrentFontScale    = RasterAttr[CursorY];
  1215.     FontScalingRequired    = FALSE;
  1216.     CharCellNominator    = 1;
  1217.  
  1218.     if(CurrentCharWidth == SCALE_HALF)
  1219.         CharCellDenominator = 2;
  1220.     else
  1221.         CharCellDenominator = 1;
  1222.  
  1223.     if(CurrentFontScale == SCALE_ATTR_NORMAL)
  1224.     {
  1225.         if(CurrentCharWidth == SCALE_HALF)
  1226.         {
  1227.                 /* Half of normal width */
  1228.  
  1229.             LastPrintableColumn    = (LastColumn + 1) * 2 - 1;
  1230.             LastPrintablePixel     = (LastPixel + 1) * 2 - 1;
  1231.             FontScalingRequired    = TRUE;
  1232.         }
  1233.         else
  1234.         {
  1235.                 /* Normal width */
  1236.  
  1237.             LastPrintableColumn    = LastColumn;
  1238.             LastPrintablePixel    = LastPixel;
  1239.         }
  1240.     }
  1241.     else
  1242.     {
  1243.         if(CurrentCharWidth == SCALE_HALF)
  1244.         {
  1245.                 /* Half of double width */
  1246.  
  1247.             LastPrintableColumn    = LastColumn;
  1248.             LastPrintablePixel    = LastPixel;
  1249.         }
  1250.         else
  1251.         {
  1252.                 /* Double width */
  1253.  
  1254.             LastPrintableColumn    = ((LastColumn + 1) / 2) - 1;
  1255.             LastPrintablePixel    = ((LastPixel + 1) / 2) - 1;
  1256.             FontScalingRequired    = TRUE;
  1257.         }
  1258.     }
  1259. }
  1260.  
  1261.     /* ConTransferUpdate():
  1262.      *
  1263.      *    Choose the right processing routine for the job.
  1264.      */
  1265.  
  1266. VOID
  1267. ConTransferUpdate()
  1268. {
  1269.     if(Translate_CR_LF)
  1270.     {
  1271.         if(XProtocolBase && (TransferBits & XPRS_HOSTMON))
  1272.             ConTransfer = (CONTRANSFER)ConTransferHost_Translate_CR_LF;
  1273.         else
  1274.             ConTransfer = (CONTRANSFER)ConProcess_Translate_CR_LF;
  1275.     }
  1276.     else
  1277.     {
  1278.         if(XProtocolBase && (TransferBits & XPRS_HOSTMON))
  1279.             ConTransfer = (CONTRANSFER)ConTransferHost;
  1280.         else
  1281.             ConTransfer = (CONTRANSFER)ConProcess;
  1282.     }
  1283. }
  1284.  
  1285. /****************************************************************************/
  1286.  
  1287.     /* ConClear():
  1288.      *
  1289.      *    Clears the console screen, no matter what emulation is
  1290.      *    currently running.
  1291.      */
  1292.  
  1293. VOID
  1294. ConClear()
  1295. {
  1296.     if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1297.         XEmulatorClearConsole(XEM_IO);
  1298.     else
  1299.     {
  1300.         if(Marking)
  1301.             WindowMarkerStop();
  1302.  
  1303.         ConRawOutput("\033[2J\033[H");
  1304.     }
  1305. }
  1306.  
  1307.     /* ConResetFont():
  1308.      *
  1309.      *    Resets the console font, no matter what emulation is
  1310.      *    currently running.
  1311.      */
  1312.  
  1313. VOID
  1314. ConResetFont()
  1315. {
  1316.     if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1317.         XEmulatorResetCharset(XEM_IO);
  1318.     else
  1319.     {
  1320.         if(Marking)
  1321.             WindowMarkerStop();
  1322.  
  1323.         CurrentFont = TextFont;
  1324.  
  1325.         SetFont(RPort,CurrentFont);
  1326.  
  1327.         ConOutputUpdate();
  1328.     }
  1329. }
  1330.  
  1331.     /* ConResetStyles():
  1332.      *
  1333.      *    Resets the console text rendering style, no matter what emulation is
  1334.      *    currently running.
  1335.      */
  1336.  
  1337. VOID
  1338. ConResetStyles()
  1339. {
  1340.     if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1341.         XEmulatorResetTextStyles(XEM_IO);
  1342.     else
  1343.     {
  1344.         if(Marking)
  1345.             WindowMarkerStop();
  1346.  
  1347.         ConRawOutput("\033[0m");
  1348.  
  1349.         ClearCursor();
  1350.  
  1351.         CurrentCharWidth = SCALE_NORMAL;
  1352.  
  1353.         if(!Config->EmulationConfig->LockColour)
  1354.         {
  1355.             ForegroundPen = GetPenIndex(SafeTextPen);
  1356.             BackgroundPen = 0;
  1357.         }
  1358.  
  1359.         UpdatePens(RPort);
  1360.  
  1361.         ConFontScaleUpdate();
  1362.  
  1363.         DrawCursor();
  1364.     }
  1365. }
  1366.  
  1367.     /* ConResetTerminal():
  1368.      *
  1369.      *    Resets the console, no matter what emulation is
  1370.      *    currently running.
  1371.      */
  1372.  
  1373. VOID
  1374. ConResetTerminal()
  1375. {
  1376.     if(XEmulatorBase && Config->TerminalConfig->EmulationMode == EMULATION_EXTERNAL)
  1377.         XEmulatorResetConsole(XEM_IO);
  1378.     else
  1379.     {
  1380.         if(Marking)
  1381.             WindowMarkerStop();
  1382.  
  1383.         ConRawOutput("\033c");
  1384.     }
  1385. }
  1386.  
  1387.     /* SetConsoleQuiet(BOOL NewSettings):
  1388.      *
  1389.      *    Tell the console to be quiet.
  1390.      */
  1391.  
  1392. BOOL
  1393. SetConsoleQuiet(BOOL NewSettings)
  1394. {
  1395.     BOOL OldSettings;
  1396.  
  1397.     OldSettings        = ConsoleQuiet;
  1398.     ConsoleQuiet    = NewSettings;
  1399.  
  1400.     return(OldSettings);
  1401. }
  1402.